SQL Server এ Advanced Query Techniques ব্যবহার করে আপনি আরও দক্ষভাবে ডেটাবেস থেকে তথ্য পুনরুদ্ধার করতে পারেন। এই টেকনিকগুলো আপনাকে জটিল ডেটাবেস স্ট্রাকচার এবং বিশাল ডেটাসেটের মধ্যে থেকে প্রয়োজনীয় ডেটা দ্রুত এবং কার্যকরভাবে বের করতে সাহায্য করবে। SQL Server এর উন্নত কুয়েরি টেকনিকগুলোর মধ্যে Subqueries, CTEs (Common Table Expressions), Joins, Window Functions, Pivoting এবং Recursive Queries ইত্যাদি অন্তর্ভুক্ত।
এই টিউটোরিয়ালে, আমরা SQL Server এর কিছু উন্নত কুয়েরি টেকনিক নিয়ে আলোচনা করব যা আপনাকে আরও শক্তিশালী এবং কার্যকর কুয়েরি তৈরি করতে সহায়তা করবে।
1. Subqueries
Subqueries হলো একটি কুয়েরি যা অন্য একটি কুয়েরির মধ্যে ব্যবহৃত হয়। এটি ডেটাবেস থেকে সঠিক ফলাফল পেতে সাহায্য করে যখন আপনি একটি নির্দিষ্ট কন্ডিশন বা মানের উপর ভিত্তি করে কুয়েরি তৈরি করেন। Subquery মূল কুয়েরির একটি অংশ হিসেবে কাজ করে এবং তা কোথাও WHERE, HAVING, FROM, বা SELECT ক্লজে ব্যবহার করা যেতে পারে।
1.1. Subquery এর উদাহরণ
ধরা যাক, আপনি এমন একটি কুয়েরি তৈরি করতে চান যেখানে সেলারির গড়ের চেয়ে বেশি সেলারি পাওয়া কর্মীদের তালিকা দেখানো হবে।
SELECT EmployeeName, Salary
FROM Employees
WHERE Salary > (SELECT AVG(Salary) FROM Employees);
এখানে, সাবকুয়েরি (SELECT AVG(Salary) FROM Employees) প্রথমে গড় সেলারি হিসাব করবে, এবং মেইন কুয়েরি সেই মানের চেয়ে বেশি সেলারি পাওয়া কর্মীদের তথ্য বের করবে।
2. Common Table Expressions (CTEs)
Common Table Expressions (CTEs) একটি অস্থায়ী ফলাফল সেট যা কুয়েরির মধ্যে পুনরায় ব্যবহার করা যেতে পারে। এটি সাবকুয়েরি এবং টেম্পোরারি টেবিলের মতো কাজ করে, তবে বেশি সহজবোধ্য এবং পাঠযোগ্য হয়।
2.1. CTE এর উদাহরণ
ধরা যাক, আপনি একটি ঐতিহাসিক ডেটাবেসে কর্মীদের বেতন তুলনা করতে চান, যেখানে আগের বছরের বেতন এবং বর্তমান বছরের বেতন তুলনা করা হবে।
WITH EmployeeSalaries AS (
SELECT EmployeeID, Salary, Year
FROM EmployeeSalaries
WHERE Year IN (2023, 2024)
)
SELECT E1.EmployeeID, E1.Salary AS Salary2024, E2.Salary AS Salary2023
FROM EmployeeSalaries E1
JOIN EmployeeSalaries E2 ON E1.EmployeeID = E2.EmployeeID
WHERE E1.Year = 2024 AND E2.Year = 2023;
এখানে, WITH ক্লজটি CTE ডিফাইন করছে, এবং EmployeeSalaries CTE-টি ডেটা ফিল্টার করার জন্য ব্যবহৃত হচ্ছে। তারপর, মূল কুয়েরিতে এই CTE ব্যবহার করা হচ্ছে।
3. Joins
Joins হল একটি SQL টেকনিক যা একাধিক টেবিলের মধ্যে সম্পর্ক তৈরি করে এবং তাদের মধ্যে ডেটা সংযুক্ত করতে সাহায্য করে। SQL Server এ মূলত ৪ ধরনের Joins ব্যবহৃত হয়:
- INNER JOIN: শুধুমাত্র সেই রেকর্ডগুলো ফেরত দেয় যা দুইটি টেবিলের মধ্যে মিলে।
- LEFT JOIN (or LEFT OUTER JOIN): বাম টেবিলের সব রেকর্ড এবং ডান টেবিলের মেলানো রেকর্ডগুলো ফেরত দেয়।
- RIGHT JOIN (or RIGHT OUTER JOIN): ডান টেবিলের সব রেকর্ড এবং বাম টেবিলের মেলানো রেকর্ডগুলো ফেরত দেয়।
- FULL JOIN (or FULL OUTER JOIN): দুইটি টেবিলের সব রেকর্ড এবং যেগুলি মেলে না, সেগুলোরও তথ্য ফেরত দেয়।
3.1. Joins এর উদাহরণ
SELECT E.EmployeeName, D.DepartmentName
FROM Employees E
INNER JOIN Departments D ON E.DepartmentID = D.DepartmentID;
এই কুয়েরি দুটি টেবিল, Employees এবং Departments কে DepartmentID এর মাধ্যমে INNER JOIN করে তাদের সম্পর্কিত তথ্য রিটার্ন করবে।
4. Window Functions
Window Functions SQL Server এ খুবই শক্তিশালী টুল, যা এক্সপ্রেশনগুলির মধ্যে অ্যাগ্রিগেট, রাঙ্কিং এবং পরিসংখ্যান হিসাব করতে সাহায্য করে, অথচ এই ফাংশনগুলি GROUP BY ব্যবহার না করেই কাজ করে।
SQL Server এর জনপ্রিয় Window Functions এর মধ্যে রয়েছে:
- ROW_NUMBER(): রেকর্ডে একটি সিকোয়েন্স নম্বর প্রদান করে।
- RANK(): একই মানের জন্য র্যাঙ্ক দিয়ে থাকে, তবে একাধিক রেকর্ডের মধ্যে গ্যাপ থাকতে পারে।
- DENSE_RANK(): র্যাঙ্ক প্রদান করে তবে গ্যাপ ছাড়াই।
- NTILE(): ডেটাকে সমান অংশে ভাগ করে।
4.1. Window Function এর উদাহরণ
SELECT EmployeeName, Salary,
ROW_NUMBER() OVER (ORDER BY Salary DESC) AS Rank
FROM Employees;
এখানে, ROW_NUMBER() ফাংশন ব্যবহার করে কর্মীদের সেলারি অনুযায়ী র্যাঙ্ক তৈরি করা হয়েছে।
5. Pivoting
Pivoting SQL Server এ ডেটাকে একটি নির্দিষ্ট কোলাম থেকে বিভিন্ন কলামে রূপান্তরিত করার প্রক্রিয়া। এটি সাধারণত রিপোর্টিং এবং অ্যানালিটিক্যাল প্রয়োজনে ব্যবহার করা হয়, যেখানে কোলামভিত্তিক ডেটা আরও সহজভাবে উপস্থাপন করা যায়।
5.1. Pivoting এর উদাহরণ
ধরা যাক, আপনার কাছে বিক্রির তথ্য রয়েছে এবং আপনি এই তথ্যকে পিভট করতে চান।
SELECT Product,
[January], [February], [March]
FROM (
SELECT Product, Month, SalesAmount
FROM Sales
) AS SourceTable
PIVOT (
SUM(SalesAmount)
FOR Month IN ([January], [February], [March])
) AS PivotTable;
এখানে, PIVOT ফাংশন ব্যবহার করে SalesAmount কে Month অনুযায়ী কলামে রূপান্তরিত করা হয়েছে।
6. Recursive Queries
Recursive Queries এমন একটি কুয়েরি যা নিজেই নিজকে কল করে এবং একটি নির্দিষ্ট শর্ত পূর্ণ না হওয়া পর্যন্ত চলতে থাকে। এটি সাধারণত Hierarchy Data (যেমন ম্যানেজমেন্ট হায়ারার্কি, ক্যাটেগরি-সাবক্যাটেগরি) থেকে ডেটা পুনরুদ্ধারে ব্যবহৃত হয়।
6.1. Recursive Query এর উদাহরণ
ধরা যাক, আপনার কাছে একটি ম্যানেজমেন্ট হায়ারার্কি টেবিল আছে, এবং আপনি জানতে চান, একটি নির্দিষ্ট ম্যানেজারের অধীনে কে কে কাজ করছে।
WITH EmployeeHierarchy AS (
SELECT EmployeeID, ManagerID, EmployeeName
FROM Employees
WHERE ManagerID IS NULL
UNION ALL
SELECT E.EmployeeID, E.ManagerID, E.EmployeeName
FROM Employees E
INNER JOIN EmployeeHierarchy EH ON E.ManagerID = EH.EmployeeID
)
SELECT * FROM EmployeeHierarchy;
এখানে, UNION ALL এবং CTE ব্যবহার করে একটি রিকর্শন তৈরি করা হয়েছে যা ম্যানেজারের অধীনে সমস্ত কর্মীদের তালিকা প্রদর্শন করবে।
সারাংশ
SQL Server এ Advanced Query Techniques ব্যবহার করে আপনি জটিল ডেটাবেস কুয়েরি খুব সহজে এবং দক্ষতার সাথে তৈরি করতে পারেন। Subqueries, CTEs, Joins, Window Functions, Pivoting, এবং Recursive Queries এর মতো কৌশলগুলো আপনাকে শক্তিশালী কুয়েরি তৈরি করতে সহায়তা করে এবং বড় ডেটাসেট থেকে প্রয়োজনীয় তথ্য দ্রুত পেতে সহায়ক হয়।
SQL তে Subqueries এবং Nested Queries হল এমন queries যা অন্য একটি query এর ভিতরে ব্যবহৃত হয়। এই দুটি টার্ম প্রায়ই একে অপরের সাথে পরিবর্তনীয়ভাবে ব্যবহৃত হলেও, তাদের মধ্যে কিছু পার্থক্য রয়েছে। সাধারণভাবে, একটি subquery হলো একটি query যা অন্য একটি query এর মধ্যে থাকে এবং nested query হলো subquery এর একটি বিশেষ ধরনের অবস্থা যেখানে একাধিক subquery একে অপরের মধ্যে থাকে।
1. Subquery (সাবকোয়েরি)
Subquery হলো এমন একটি SQL query যা অন্য একটি query এর মধ্যে ব্যবহৃত হয়, সাধারণত SELECT, INSERT, UPDATE, বা DELETE কমান্ডের মধ্যে। সাবকোয়েরি সাধারণত মূল query এর জন্য শর্ত বা মান প্রদান করে। সাবকোয়েরি একটি query এর ফলাফল হিসেবে কাজ করে এবং মূল query তে একটি শর্ত হিসাবে ব্যবহৃত হয়।
Subquery এর ধরন:
- Single-row subquery: একক রেকর্ড রিটার্ন করে।
- Multiple-row subquery: একাধিক রেকর্ড রিটার্ন করে।
- Correlated subquery: মূল query এর সাথে সম্পর্কিত হয়।
Syntax:
SELECT column1, column2, ...
FROM table_name
WHERE column_name operator (SELECT column_name FROM table_name WHERE condition);
উদাহরণ:
ধরা যাক, আমরা Employees টেবিল থেকে এমন সব কর্মচারীর নাম চাই, যারা 30 বছরের বেশি বয়সী এবং তাদের উপর নির্ধারিত বোনাস (Bonus) এর পরিমাণ 1000 এর বেশি।
SELECT FirstName, LastName
FROM Employees
WHERE EmployeeID IN (SELECT EmployeeID FROM Bonuses WHERE Amount > 1000);
এখানে, ভিতরের subquery (SELECT EmployeeID FROM Bonuses WHERE Amount > 1000) প্রথমে সব EmployeeID বের করবে যাদের বোনাস 1000 এর বেশি। তারপর বাইরের SELECT query সেই EmployeeID এর সাথে মিলে যাওয়া Employees টেবিল থেকে কর্মচারীদের নাম রিটার্ন করবে।
2. Correlated Subquery (কোরেলেটেড সাবকোয়েরি)
Correlated subquery হল এমন একটি subquery যা বাইরের query এর কলাম থেকে মান নেয়। অর্থাৎ, এই subquery এর ফলাফল বাইরের query এর প্রতিটি রেকর্ডের উপর নির্ভর করে।
উদাহরণ:
ধরা যাক, আমাদের কাছে একটি Employees টেবিল এবং একটি Salaries টেবিল রয়েছে। আমরা এমন কর্মচারীদের নাম চাই, যারা নিজের পুরানো বেতন থেকে বেশি বেতন পাচ্ছে। এখানে একটি correlated subquery ব্যবহার করা হবে:
SELECT e.FirstName, e.LastName
FROM Employees e
WHERE e.Salary > (SELECT s.Salary FROM Salaries s WHERE s.EmployeeID = e.EmployeeID);
এখানে, subquery এর মধ্যে e.EmployeeID ব্যবহার করা হয়েছে, যা বাইরের query এর কলাম থেকে নেয়। ফলে এটি correlated subquery। সাবকোয়েরিটি বাইরের query এর প্রতিটি রেকর্ডের সাথে সম্পর্কিত থাকে।
3. Nested Queries (নেস্টেড কোয়েরি)
Nested Query বলতে বোঝানো হয় একটি query এর মধ্যে আরও একটি বা একাধিক query ব্যবহৃত। Nested query সাধারণত subquery হিসেবে ব্যবহৃত হয়, তবে একাধিক subquery গুলি একে অপরের মধ্যে নেস্টেড থাকতে পারে। Nested query এর মাধ্যমে বিভিন্ন ধরণের জটিল ডেটা রিটার্ন করা যায়।
উদাহরণ:
ধরা যাক, Orders এবং Customers টেবিল রয়েছে এবং আপনি এমন গ্রাহকদের নাম জানতে চান, যারা এমন সব অর্ডার করেছেন, যেখানে মোট অর্ডার মূল্য 5000 এর বেশি।
SELECT CustomerName
FROM Customers
WHERE CustomerID IN
(SELECT CustomerID
FROM Orders
WHERE TotalAmount > 5000);
এখানে, nested query (যেটি Orders টেবিলের উপর চলে) প্রথমে সমস্ত CustomerID বের করবে, যাদের মোট অর্ডার মূল্য 5000 এর বেশি। তারপর বাইরের query সেই CustomerID গুলি অনুযায়ী গ্রাহকের নাম বের করবে।
4. Types of Subqueries
4.1 Single-Row Subquery (একক-রেকর্ড সাবকোয়েরি)
এটি এমন একটি subquery যা শুধুমাত্র একটি একক রেকর্ড রিটার্ন করে। এটি সাধারণত = (ইকুয়াল), <, >, <=, >=, এবং <> অপারেটরদের সাথে ব্যবহৃত হয়।
উদাহরণ:
SELECT FirstName, LastName
FROM Employees
WHERE EmployeeID = (SELECT EmployeeID FROM Employees WHERE FirstName = 'John' AND LastName = 'Doe');
এখানে, subquery একটি মাত্র EmployeeID রিটার্ন করবে যেটি EmployeeID এর সাথে বাইরের query তে মিলিয়ে FirstName এবং LastName প্রদর্শন করবে।
4.2 Multiple-Row Subquery (একাধিক-রেকর্ড সাবকোয়েরি)
এটি এমন একটি subquery যা একাধিক রেকর্ড রিটার্ন করে। এটি সাধারণত IN, ANY, বা ALL অপারেটরের সাথে ব্যবহৃত হয়।
উদাহরণ:
SELECT FirstName, LastName
FROM Employees
WHERE EmployeeID IN (SELECT EmployeeID FROM Orders WHERE OrderDate > '2024-01-01');
এখানে, subquery সমস্ত EmployeeID রিটার্ন করবে যাদের Orders টেবিলের মধ্যে অর্ডার তারিখ 2024-01-01 এর পর।
5. Performance Considerations for Subqueries
যদিও subqueries শক্তিশালী এবং নমনীয়, তবে তাদের ব্যবহার পারফরম্যান্স সমস্যাও তৈরি করতে পারে, বিশেষত যখন বড় ডেটাবেস বা জটিল subqueries ব্যবহার করা হয়। কিছু পরামর্শ:
- Indexed columns ব্যবহার করুন: যেসব কলামগুলো WHERE, IN, বা JOIN শর্তে ব্যবহৃত হয়, তাদের উপর ইনডেক্স রাখা পারফরম্যান্স উন্নত করতে পারে।
- Joins এর মাধ্যমে Subqueries প্রতিস্থাপন করুন: কিছু সময় subquery এর পরিবর্তে JOIN ব্যবহার করা পারফরম্যান্সের জন্য ভালো হতে পারে।
সারাংশ
Subqueries এবং Nested Queries SQL তে ডেটা ম্যানিপুলেশন এবং চয়ন করার জন্য শক্তিশালী টুলস। Subqueries বাইরের query এর জন্য একটি অন্তর্নিহিত শর্ত বা মান প্রদান করে, আর Nested Queries একাধিক subquery একে অপরের মধ্যে থাকে। এই টেকনিকগুলোর সঠিক ব্যবহার ডেটাবেস থেকে জটিল তথ্য খুব দ্রুত এবং কার্যকরভাবে বের করতে সাহায্য করে।
Common Table Expressions (CTE) হল SQL এর একটি শক্তিশালী ফিচার যা জটিল কোয়েরি লিখতে এবং পড়তে সহজ করে তোলে। CTE গুলি সাধারণত SELECT, INSERT, UPDATE, এবং DELETE কমান্ডগুলোর সাথে ব্যবহৃত হয় এবং কোয়েরির মধ্যে বা কোয়েরি নেস্টিংকে সহজ করে তোলে। CTE ব্যবহার করে কোডের পুনরাবৃত্তি কমানো এবং কোডের গঠন উন্নত করা যায়। এটি বিশেষত যখন আপনি একাধিক স্টেপে ডেটা ট্রান্সফর্ম করছেন তখন খুবই কার্যকরী।
1. CTE কী?
CTE হলো একটি নামকৃত তাত্ক্ষণিক টেবিল যা WITH কিওয়ার্ড দিয়ে SQL কোয়েরির শুরুতে ডিফাইন করা হয়। CTE টেবিলের মতো ব্যবহার করা যেতে পারে এবং এটি কোয়েরির মধ্যে একাধিকবার রেফারেন্স করা যেতে পারে। CTE কোডের গঠন পরিষ্কার এবং কমপ্যাক্ট করে তোলে, বিশেষ করে যখন আপনি একটি সাব-কোয়্যারি বা নেস্টেড কোয়েরি বারবার ব্যবহার করতে চান।
CTE এর সুবিধা:
- Code Reusability: একাধিক জায়গায় একই কোয়েরি ব্যবহার করতে পারবেন।
- Readability: কোডকে আরও পরিষ্কার এবং সহজভাবে উপস্থাপন করা যায়।
- Recursive Queries: CTE এর মাধ্যমে রিকার্সিভ কোয়েরি তৈরি করা যায়, যা হায়ারার্কিকাল ডেটার জন্য খুবই উপকারী।
2. CTE এর সিনট্যাক্স
CTE ডিফাইন করতে WITH কিওয়ার্ড ব্যবহার করা হয় এবং এরপর CTE এর নাম, কলাম নাম এবং মূল কোয়েরি দেওয়া হয়।
সাধারণ সিনট্যাক্স:
WITH CTE_Name (column1, column2, ...)
AS
(
SELECT column1, column2, ...
FROM table_name
WHERE condition
)
SELECT * FROM CTE_Name;
- CTE_Name: CTE এর নাম যা আপনি পরে কোয়েরির মধ্যে ব্যবহার করবেন।
- column1, column2, ...: CTE তে যে কলামগুলো থাকবে সেগুলোর নাম।
- SELECT: CTE তে কোয়েরি যা ডেটা রিট্রাইভ করবে।
3. CTE এর উদাহরণ
3.1. সাধারণ CTE উদাহরণ
ধরা যাক, আমাদের একটি Employees টেবিল আছে এবং আমরা একটি নির্দিষ্ট শর্তে কর্মচারীদের নাম এবং তাদের বিভাগ দেখতে চাই।
WITH EmployeeCTE AS
(
SELECT EmployeeID, FirstName, LastName, Department
FROM Employees
WHERE Department = 'Sales'
)
SELECT * FROM EmployeeCTE;
এখানে, EmployeeCTE নামক একটি CTE ডিফাইন করা হয়েছে, যা Sales বিভাগের কর্মচারীদের নির্বাচন করে এবং তারপর সেই CTE থেকে ডেটা রিট্রাইভ করা হয়েছে।
3.2. CTE ব্যবহার করে অগ্রাধিকার ভিত্তিক প্রশ্ন
ধরা যাক, আমাদের একটি Orders টেবিল আছে এবং আমরা প্রতিটি গ্রাহকের সর্বাধিক অর্ডারের ডেটা চাই।
WITH MaxOrders AS
(
SELECT CustomerID, MAX(OrderDate) AS LatestOrderDate
FROM Orders
GROUP BY CustomerID
)
SELECT o.CustomerID, o.OrderID, o.OrderDate
FROM Orders o
JOIN MaxOrders m ON o.CustomerID = m.CustomerID
AND o.OrderDate = m.LatestOrderDate;
এখানে, প্রথমে একটি CTE (MaxOrders) তৈরি করা হয়েছে, যা প্রতিটি গ্রাহকের সর্বাধিক অর্ডারের তারিখ বের করবে। তারপর মূল কোয়েরিতে সেই তথ্য ব্যবহার করে আমরা সেই সর্বাধিক অর্ডারের বিস্তারিত দেখতে পাচ্ছি।
4. Recursive CTE
Recursive CTE হল এমন একটি CTE যা নিজেকে পুনরাবৃত্তি করতে সক্ষম। এটি হায়ারার্কিকাল ডেটা (যেমন এমপ্লয়ির ম্যানেজার হায়ারার্কি, ফোল্ডার স্ট্রাকচার ইত্যাদি) নেভিগেট করতে ব্যবহার করা হয়।
সিনট্যাক্স:
WITH RecursiveCTE AS
(
-- Base Case: Start with initial row(s)
SELECT column1, column2
FROM table_name
WHERE condition
UNION ALL
-- Recursive Case: Reference the CTE itself
SELECT t.column1, t.column2
FROM table_name t
INNER JOIN RecursiveCTE r ON t.column1 = r.column2
)
SELECT * FROM RecursiveCTE;
উদাহরণ:
ধরা যাক, আমাদের একটি Employees টেবিল আছে এবং আমরা একটি হায়ারার্কিকাল কাঠামোতে কর্মচারীদের এবং তাদের ম্যানেজারদের সম্পর্ক দেখতে চাই।
WITH EmployeeHierarchy AS
(
SELECT EmployeeID, ManagerID, Name
FROM Employees
WHERE ManagerID IS NULL -- Base case: Top-level managers
UNION ALL
SELECT e.EmployeeID, e.ManagerID, e.Name
FROM Employees e
INNER JOIN EmployeeHierarchy eh ON e.ManagerID = eh.EmployeeID -- Recursive case
)
SELECT * FROM EmployeeHierarchy;
এখানে, প্রথমে Base case এ যেসব ম্যানেজারদের ManagerID NULL (টপ-লেভেল) তাদের নির্বাচন করা হয়েছে। তারপর Recursive case এ কর্মচারীদের নির্বাচিত করা হয়েছে যারা তাদের ম্যানেজারের অধীনে কাজ করছে।
5. CTE এর সীমাবদ্ধতা
- CTE গুলি শুধুমাত্র একটি SQL কোয়েরি চলাকালীন বৈধ থাকে। একবার কোয়েরি রান হয়ে গেলে CTE টির অবস্থা শেষ হয়ে যায়।
- CTE এর মধ্যে আপনি INSERT, UPDATE, DELETE কমান্ডও ব্যবহার করতে পারেন, তবে আপনাকে সতর্ক থাকতে হবে যেন CTE এর রেকর্ডগুলিতে কোনো অনিচ্ছাকৃত পরিবর্তন না হয়।
- CTE এর মাধ্যমে খুব বড় ডেটাসেট থেকে ডেটা নির্বাচন করলে পারফরম্যান্সে প্রভাব পড়তে পারে, বিশেষত যখন এটি রিকার্সিভ হয়।
সারাংশ
CTE (Common Table Expression) SQL এর একটি শক্তিশালী বৈশিষ্ট্য যা ডেটাবেস কোয়েরি লেখার জন্য পরিষ্কার এবং ম্যানেজেবল কোড প্রদান করে। এটি সাধারণত কোডের পুনঃব্যবহার এবং ডেটা ম্যানিপুলেশনকে আরও সহজ এবং দক্ষ করে তোলে। বিশেষত, Recursive CTE ব্যবহার করে হায়ারার্কিকাল ডেটা পরিচালনা করা অনেক সহজ হয়।
SQL এর UNION, INTERSECT, এবং EXCEPT অপারেটরগুলি একসাথে ডেটাবেসের টেবিলের তথ্য ম্যানিপুলেট করার জন্য ব্যবহৃত হয়। এগুলি বিভিন্ন কুয়েরি থেকে ডেটা একত্রিত, মিলিত, বা পার্থক্য নির্ধারণ করার জন্য ব্যবহৃত হয়। এই অপারেটরগুলির ব্যবহার সাধারণত তখনই হয় যখন একাধিক SELECT কুয়েরি থেকে ডেটা একত্রিত করতে বা তুলনা করতে হয়।
1. UNION – দুটি বা ততোধিক কুয়েরি থেকে ডেটা একত্রিত করা
UNION অপারেটর দুটি বা তার বেশি SELECT কুয়েরি থেকে ডেটা একত্রিত করে। এটি একমাত্র ইউনিক (distinct) রেকর্ডস ফিরিয়ে দেয়, অর্থাৎ ডুপ্লিকেট রেকর্ড বাদ দিয়ে কেবল একবার প্রদর্শন করবে।
1.1. UNION এর সাধারণ সিনট্যাক্স:
SELECT column1, column2
FROM table1
UNION
SELECT column1, column2
FROM table2;
- এখানে, দুটি SELECT কুয়েরি একত্রিত হচ্ছে এবং ডুপ্লিকেট রেকর্ড বাদ দিয়ে ইউনিক রেকর্ডগুলো দেখানো হচ্ছে।
1.2. UNION উদাহরণ:
ধরা যাক, আপনার দুটি টেবিল আছে: Employees_Dept1 এবং Employees_Dept2, এবং আপনি দুটো টেবিলের সকল কর্মচারীর নাম একত্রিত করতে চান:
SELECT Name
FROM Employees_Dept1
UNION
SELECT Name
FROM Employees_Dept2;
এখানে UNION কুয়েরি দুটি টেবিল থেকে সকল ইউনিক কর্মচারীর নাম একত্রিত করবে। যেকোনো ডুপ্লিকেট নাম শুধুমাত্র একবার দেখাবে।
1.3. UNION ALL এর ব্যবহার:
যদি আপনি ডুপ্লিকেট রেকর্ড অন্তর্ভুক্ত করতে চান, তাহলে UNION ALL ব্যবহার করতে হবে। এটি সমস্ত রেকর্ড, ডুপ্লিকেট সহ, ফিরিয়ে দেবে।
SELECT Name
FROM Employees_Dept1
UNION ALL
SELECT Name
FROM Employees_Dept2;
এখানে UNION ALL কুয়েরি দুটি টেবিল থেকে সব কর্মচারীর নাম দেখাবে, ডুপ্লিকেটসহ।
2. INTERSECT – দুটি কুয়েরির মিলিত ডেটা নির্বাচন
INTERSECT অপারেটর দুটি SELECT কুয়েরি থেকে কেবলমাত্র মিলিত (common) রেকর্ডগুলো নির্বাচন করে। অর্থাৎ, এটি দুটি কুয়েরি থেকে কেবল সেই রেকর্ডগুলো দেখাবে, যেগুলি উভয় কুয়েরি থেকেই পাওয়া যাবে।
2.1. INTERSECT এর সাধারণ সিনট্যাক্স:
SELECT column1, column2
FROM table1
INTERSECT
SELECT column1, column2
FROM table2;
- এখানে, দুটি SELECT কুয়েরির মধ্যে যেসব রেকর্ড মিল আছে, কেবলমাত্র সেগুলিই নির্বাচিত হবে।
2.2. INTERSECT উদাহরণ:
ধরা যাক, আপনার দুটি টেবিল রয়েছে Employees_Dept1 এবং Employees_Dept2, এবং আপনি দেখতে চান, কোন কর্মচারী দুটি টেবিলেই উপস্থিত আছে:
SELECT Name
FROM Employees_Dept1
INTERSECT
SELECT Name
FROM Employees_Dept2;
এখানে INTERSECT কেবলমাত্র সেই কর্মচারীদের নাম নির্বাচন করবে যারা উভয় টেবিলেই উপস্থিত রয়েছে।
3. EXCEPT – একটি কুয়েরির ডেটা অন্য কুয়েরি থেকে বাদ দেওয়া
EXCEPT অপারেটর দুটি SELECT কুয়েরি থেকে প্রথম কুয়েরির রেকর্ড গুলি, যেগুলি দ্বিতীয় কুয়েরি তে নেই, তা নির্বাচন করে। এটি প্রথম কুয়েরির ডেটা থেকে দ্বিতীয় কুয়েরির ডেটা বাদ দেয়।
3.1. EXCEPT এর সাধারণ সিনট্যাক্স:
SELECT column1, column2
FROM table1
EXCEPT
SELECT column1, column2
FROM table2;
- এখানে, প্রথম কুয়েরির সকল রেকর্ডগুলির মধ্যে সেই রেকর্ডগুলি নির্বাচন করা হবে যা দ্বিতীয় কুয়েরিতে নেই।
3.2. EXCEPT উদাহরণ:
ধরা যাক, আপনার দুটি টেবিল রয়েছে Employees_Dept1 এবং Employees_Dept2, এবং আপনি দেখতে চান কোন কর্মচারীরা Employees_Dept1 টেবিলে আছেন কিন্তু Employees_Dept2 টেবিলে নেই:
SELECT Name
FROM Employees_Dept1
EXCEPT
SELECT Name
FROM Employees_Dept2;
এখানে EXCEPT কেবলমাত্র সেই কর্মচারীদের নাম দেখাবে যারা Employees_Dept1 টেবিলে আছেন, কিন্তু Employees_Dept2 টেবিলে নেই।
4. অপারেটরগুলির মধ্যে পার্থক্য
| অপারেটর | বর্ণনা | ডুপ্লিকেট রেকর্ড | মিলিত রেকর্ড | ব্যবহারের উদাহরণ |
|---|---|---|---|---|
| UNION | দুটি কুয়েরি থেকে ইউনিক রেকর্ড একত্রিত করে | বাদ দেওয়া | দুটি কুয়েরির মিলিত রেকর্ডগুলো | কর্মচারী নাম একত্রিত করা |
| UNION ALL | সমস্ত রেকর্ড (ডুপ্লিকেট সহ) একত্রিত করে | অন্তর্ভুক্ত | সমস্ত রেকর্ড | একাধিক টেবিলের সব ডেটা একত্রিত করা |
| INTERSECT | দুটি কুয়েরি থেকে মিলিত রেকর্ড নির্বাচন করে | বাদ দেওয়া | দুটি কুয়েরির মিলিত রেকর্ড | দুটি টেবিলের মিলিত ডেটা দেখানো |
| EXCEPT | প্রথম কুয়েরির ডেটা দ্বিতীয় কুয়েরি থেকে বাদ দিয়ে দেখায় | বাদ দেওয়া | প্রথম কুয়েরির এক্সক্লুসিভ ডেটা | প্রথম টেবিলের ডেটা যেটি দ্বিতীয় টেবিলে নেই |
সারাংশ
UNION, INTERSECT, এবং EXCEPT অপারেটরগুলি SQL এ ডেটা একত্রিত, মিলিত বা বাদ দেওয়ার জন্য ব্যবহৃত হয়। UNION বিভিন্ন কুয়েরি থেকে ইউনিক ডেটা একত্রিত করে, INTERSECT কেবল মিলিত ডেটা প্রদান করে, এবং EXCEPT একটি কুয়েরি থেকে অপর কুয়েরির ডেটা বাদ দেয়। এগুলোর সঠিক ব্যবহার ডেটাবেস কুয়েরি উন্নত করতে সাহায্য করে এবং নির্দিষ্ট ডেটা নির্বাচন করতে কার্যকর।
Window Functions SQL এ একটি শক্তিশালী ফিচার যা একাধিক রেকর্ডের মধ্যে নির্দিষ্ট নিয়মে বিশ্লেষণ করতে সহায়তা করে। এগুলো সাধারণত OVER() ক্লজ ব্যবহার করে পরিচালিত হয় এবং বিভিন্ন রেকর্ডের মধ্যে ক্যালকুলেশন বা পারফরম্যান্স নির্ধারণ করতে ব্যবহৃত হয়।
এসব ফাংশন ডেটার কোন নির্দিষ্ট সারণী বা পার্টিশনে কাজ করে এবং একই সাথে রেকর্ডগুলোর অবস্থান বা স্থান অনুসারে গাণিতিক/স্ট্যাটিস্টিক্যাল বিশ্লেষণ করতে সহায়তা করে।
এখানে চারটি গুরুত্বপূর্ণ Window Function আলোচনা করা হচ্ছে:
- ROW_NUMBER()
- RANK()
- LEAD()
- LAG()
1. ROW_NUMBER()
ROW_NUMBER() ফাংশনটি রেকর্ডগুলোর মধ্যে প্রতিটি রেকর্ডকে একটি অনন্য সিরিয়াল নম্বর (row number) অ্যাসাইন করে, যা সারণীতে নির্দিষ্ট ক্রম অনুসারে প্রদর্শিত হয়। এটি সাধারণত রেকর্ডের স্থান নির্ধারণের জন্য ব্যবহৃত হয়।
সিনট্যাক্স:
SELECT column1, column2, ROW_NUMBER() OVER (ORDER BY column_name) AS row_num
FROM table_name;
- ROW_NUMBER() ফাংশনটি কেবল রেকর্ডের অবস্থান বা সিরিয়াল নম্বর প্রদানের জন্য ব্যবহৃত হয়, এবং এর মাধ্যমে একই মানের জন্য আলাদা সিরিয়াল নম্বর তৈরি হয়।
উদাহরণ:
ধরা যাক, একটি Sales টেবিল রয়েছে এবং আমরা বিক্রেতাদের নামের ভিত্তিতে প্রতিটি রেকর্ডের জন্য একটি সিরিয়াল নম্বর তৈরি করতে চাই।
SELECT sales_rep, sales_amount, ROW_NUMBER() OVER (ORDER BY sales_amount DESC) AS row_num
FROM Sales;
এটি sales_amount কলামের ভিত্তিতে একটি সিরিয়াল নম্বর তৈরি করবে, এবং যে রেকর্ডটির সর্বোচ্চ বিক্রয় হবে সেটি প্রথমে থাকবে।
2. RANK()
RANK() ফাংশনটি ROW_NUMBER() এর মতো কাজ করে, তবে এটি দুটি বা তার বেশি একীভূত মানের জন্য একই র্যাঙ্ক (rank) প্রদান করে। RANK() ফাংশন একক মানের জন্য একটি বিশেষ র্যাঙ্ক প্রদান করে, কিন্তু যদি একাধিক রেকর্ড একই মানের হয়, তবে তাদের সবাইকে একই র্যাঙ্ক দেওয়া হয় এবং পরবর্তী র্যাঙ্কটি একাধিক ধাপ এগিয়ে চলে।
সিনট্যাক্স:
SELECT column1, column2, RANK() OVER (ORDER BY column_name) AS rank
FROM table_name;
উদাহরণ:
ধরা যাক, আমাদের একটি Employees টেবিল রয়েছে এবং আমরা তাদের বেতন অনুযায়ী র্যাঙ্ক করতে চাই।
SELECT employee_name, salary, RANK() OVER (ORDER BY salary DESC) AS rank
FROM Employees;
এটি কর্মীদের বেতন অনুযায়ী তাদের র্যাঙ্ক প্রদান করবে। যদি দুটি কর্মীর বেতন সমান থাকে, তাদের উভয়ের জন্য একই র্যাঙ্ক হবে, এবং পরবর্তী র্যাঙ্কটি দুটি ধাপ এগিয়ে থাকবে।
3. LEAD()
LEAD() ফাংশনটি বর্তমান রেকর্ডের পরবর্তী রেকর্ডের মান দেখানোর জন্য ব্যবহৃত হয়। এটি মূলত কোন কলামের মানের পরবর্তী রেকর্ডের সাথে তুলনা করতে সাহায্য করে এবং এটি কেবল ফলস্বরূপে ব্যবহৃত হয় যেখানে পরবর্তী রেকর্ডের ডেটা প্রয়োজন হয়।
সিনট্যাক্স:
SELECT column1, column2, LEAD(column_name, 1) OVER (ORDER BY column_name) AS next_value
FROM table_name;
- LEAD() ফাংশনটি বর্তমান রেকর্ডের পরবর্তী রেকর্ডের মান ফিরিয়ে দেয়, এবং এখানে দ্বিতীয় আর্গুমেন্ট 1 দ্বারা পরবর্তী রেকর্ড নির্দেশ করা হয়েছে।
উদাহরণ:
ধরা যাক, আমাদের একটি Sales টেবিল রয়েছে এবং আমরা প্রতিটি বিক্রেতার বিক্রয় পরিমাণ এবং তাদের পরবর্তী বিক্রয় পরিমাণ দেখতে চাই।
SELECT sales_rep, sales_amount, LEAD(sales_amount, 1) OVER (ORDER BY sales_date) AS next_sales
FROM Sales;
এটি sales_amount কলামের বর্তমান মানের পাশাপাশি পরবর্তী রেকর্ডের sales_amount দেখাবে, যা বিক্রয়ের পরবর্তী তারিখের উপর ভিত্তি করে।
4. LAG()
LAG() ফাংশনটি LEAD() এর বিপরীত কাজ করে, অর্থাৎ এটি বর্তমান রেকর্ডের পূর্ববর্তী রেকর্ডের মান দেখানোর জন্য ব্যবহৃত হয়। এটি মূলত কোনো রেকর্ডের আগের রেকর্ডের তথ্য দেখতে সাহায্য করে।
সিনট্যাক্স:
SELECT column1, column2, LAG(column_name, 1) OVER (ORDER BY column_name) AS previous_value
FROM table_name;
- LAG() ফাংশনটি বর্তমান রেকর্ডের পূর্ববর্তী রেকর্ডের মান ফিরিয়ে দেয়, এবং দ্বিতীয় আর্গুমেন্ট 1 দ্বারা পূর্ববর্তী রেকর্ড নির্দেশ করা হয়েছে।
উদাহরণ:
ধরা যাক, আমাদের একটি Sales টেবিল রয়েছে এবং আমরা প্রতিটি বিক্রেতার বিক্রয় পরিমাণ এবং তাদের পূর্ববর্তী বিক্রয় পরিমাণ দেখতে চাই।
SELECT sales_rep, sales_amount, LAG(sales_amount, 1) OVER (ORDER BY sales_date) AS previous_sales
FROM Sales;
এটি sales_amount কলামের বর্তমান মানের পাশাপাশি পূর্ববর্তী রেকর্ডের sales_amount দেখাবে, যা বিক্রয়ের আগের তারিখের উপর ভিত্তি করে।
সারাংশ
- ROW_NUMBER(): প্রতিটি রেকর্ডের জন্য একটি অনন্য সিরিয়াল নম্বর প্রদান করে।
- RANK(): একাধিক সমান মানের জন্য একই র্যাঙ্ক প্রদান করে এবং পরবর্তী র্যাঙ্কটি ধাপে এগিয়ে চলে।
- LEAD(): বর্তমান রেকর্ডের পরবর্তী রেকর্ডের মান দেখায়।
- LAG(): বর্তমান রেকর্ডের পূর্ববর্তী রেকর্ডের মান দেখায়।
এই window functions SQL এ ডেটার বিশ্লেষণ এবং রিপোর্ট তৈরির জন্য শক্তিশালী টুল হিসেবে কাজ করে, বিশেষত যখন আপনাকে একাধিক রেকর্ডের মধ্যে সম্পর্ক নির্ধারণ করতে হয় বা ট্রেন্ড ও পারফরম্যান্স বিশ্লেষণ করতে হয়।
Read more